package com.fulu.netty.luban.thirddemo;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

public class TestServerHandler extends SimpleChannelInboundHandler<String> {

    private static ChannelGroup group = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /**
     *  channel活跃，通道准备就绪事件
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        group.writeAndFlush(channel.remoteAddress() + " > 准备就绪，上线,当前在线人数：" + group.size() + "\n");
    }

    /**
     * 连接加入事件的回调
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        // 获取到当前连接过来的channel
        Channel channel = ctx.channel();
        // 向这个聊天组里的所有客户端发送消息，提示谁连接过来了。
        group.writeAndFlush(channel.remoteAddress() + " > 连接\n");
        // 将这个新连接过来的channel加入到聊天组
        group.add(channel);
    }

    /**
     * channel生命结束
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        group.writeAndFlush(channel.remoteAddress() + " > 下线,当前在线人数：" + group.size() + "\n");
    }

    /**
     * 通道移除
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        group.writeAndFlush(channel.remoteAddress() + " > 离开\n");
    }

    /**
     * channel接收到数据，并转发给其他channel
     * @param channelHandlerContext
     * @param s
     * @throws Exception
     */
    @Override
    protected void messageReceived(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
        Channel channel = channelHandlerContext.channel();
        group.stream().filter(c -> !c.equals(channel)).forEach(c -> c.writeAndFlush(channel.remoteAddress() + " > " + s + "\r\n"));
        // 传播到下一个事件，向下一个handler传播，交给下一个入栈服务器
        channelHandlerContext.fireChannelRead(s);
    }
}
